/*
 * Copyright (c) 2011 Auzingers
 * Created by Oui-IT
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.auzingers.docsorganizer.entity;

import com.auzingers.docsorganizer.googleapi.GoogleRefUtil;
import com.google.common.base.Objects;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/** Base class for google entries like documents and collections. */
public abstract class GoogleEntry implements Comparable<GoogleEntry> {

    /**
     * This is the url including the id, i.e. https://docs.google.com/feeds/id/folder%3
     * A0B0oZ3CeNrlNMYjMxMTgxNjYtNGE0Yy00Zjc1LTk5M2ItZmQ3MTAyZTk4ZGIy
     */
    private String id;

    /**
     * This is the type and id, i.e.
     * folder:0B0oZ3CeNrlNMYjMxMTgxNjYtNGE0Yy00Zjc1LTk5M2ItZmQ3MTAyZTk4ZGIy
     */
    private String resourceId;

    /** This is the title displayed. */
    private String title;

    /**
     * Links to the parent collections, i.e.
     * "https://docs.google.com/feeds/default/private/
     *   full/folder%3A0B0oZ3CeNrlNMM2NiNDY1YjctMDQ4MC00M2Y0LTlkOTItNDZlN2ZmYjU4YmIy".
     */
    private List<String> parentRefs = new LinkedList<String>();

    /**
     * Short links to the parent collections, i.e.
     *   "folder%3A0B0oZ3CeNrlNMM2NiNDY1YjctMDQ4MC00M2Y0LTlkOTItNDZlN2ZmYjU4YmIy".
     */
    private List<String> parentShortRefs = new LinkedList<String>();

    /** Author of this Google entry. */
    private GoogleAuthor author = null;

    /** Convenience flag - set if author of entry and author of feed are different. */
    private boolean sharedEntry = false;

    /** Category, i.e. 'spreadsheet'. */
    private String categoryKind = null;

    // ---------- Setter and Getter ------------------------

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getResourceId() {
        return resourceId;
    }

    public void setResourceId(String resourceId) {
        this.resourceId = resourceId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<String> getParentRefs() {
        return Collections.unmodifiableList(parentRefs);
    }

    public List<String> getParentShortRefs() {
        return Collections.unmodifiableList(parentShortRefs);
    }

    /**
     * Sets all the parent references.
     * @param parentRefs references to set
     */
    public void setParentRefs(List<String> parentRefs) {
        this.parentRefs = new LinkedList<String>(parentRefs);
        parentShortRefs = new LinkedList<String>();
        for (final String ref : parentRefs) {
            parentShortRefs.add(GoogleRefUtil.stripRef(ref));
        }
    }

    public GoogleAuthor getAuthor() {
        return author;
    }

    public void setAuthor(GoogleAuthor author) {
        this.author = author;
    }

    public boolean isSharedEntry() {
        return sharedEntry;
    }

    public void setSharedEntry(boolean sharedEntry) {
        this.sharedEntry = sharedEntry;
    }

    public String getCategoryKind() {
        return categoryKind;
    }

    public void setCategoryKind(String categoryKind) {
        this.categoryKind = categoryKind;
    }

    // ---------- Convenience methods ----------------------

    /**
     * Adds a new parent reference.
     * @param ref reference to add
     */
    public void addParentRef(String ref) {
        parentRefs.add(ref);
        parentShortRefs.add(GoogleRefUtil.stripRef(ref));
    }

    /**
     * Returns the resource id without the type (i.e. without 'folder:').
     * @return see above
     */
    public String getSimpleResourceId() {
        final String result;
        if (resourceId == null) {
            result = null;
        } else {
            final int index = resourceId.indexOf(":");
            result = index >= 0 ? resourceId.substring(index + 1) : resourceId;
        }
        return result;
    }

    // ---------- Overriden methods ------------------------

    /** {@inheritDoc} */
    public int compareTo(GoogleEntry another) {
        final String otherTitle = another.getTitle();
        if (this instanceof GoogleDocument && another instanceof GoogleCollection) {
            return 1;
        } else if (this instanceof GoogleCollection && another instanceof GoogleDocument) {
            return -1;
        } else if (title == null && otherTitle == null) {
            return 0;
        } else if (title == null) {
            return 1;
        } else if (otherTitle == null) {
            return -1;
        }
        return title.compareTo(another.getTitle());
    }

    @Override
    public String toString() {
        return title;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(resourceId);
    }

    @Override
    public boolean equals(Object obj) {
        final boolean result;
        if (obj instanceof GoogleEntry) {
            final GoogleEntry other = (GoogleEntry) obj;
            result = Objects.equal(other.resourceId, resourceId);
        } else {
            result = false;
        }
        return result;
    }
}
